import goods from './data.js'

class GoodsInfo {
  constructor(g) {
    // 冻结goods对象使其不可变
    const frozenGoods = Object.freeze({ ...g })

    // 定义只读的goods属性
    Object.defineProperty(this, 'goods', {
      get() {
        return frozenGoods
      },
      set() {
        throw new Error('goods属性是只读的，不能重新赋值')
      },
      configurable: false
    })

    // 使用私有字段存储choose值
    let _choose = 0

    // 定义带验证的choose属性
    Object.defineProperty(this, 'choose', {
      get() {
        return _choose
      },
      set(val) {
        if (!Number.isInteger(val) || val < 0) {
          throw new Error('choose属性必须是大于等于0的整数')
        }
        _choose = val
      },
      configurable: false
    })

    // 密封对象
    Object.seal(this)
  }
}

class OrderInfo {
  AddGoods(index) {
    this.goodsList[index].choose++
    console.log(this.goodsList[index].choose)
  }

  ReduceGoods(index) {
    if (this.goodsList[index]._choose <= 0) return
    this.goodsList[index].choose--
    console.log(this.goodsList[index].choose)
  }

  GetTotalPrice() {
    var total = 0
    var choosedGoods = this.GetChoosedGoods()
    choosedGoods.forEach((item) => {
      total += item.goods.price * item.choose
    })
    total = parseFloat(total.toFixed(2))
    return total
  }

  MeetDeliveryShreshold() {
    return this.GetTotalPrice() >= this.deliveryShreshold
  }

  GetMinDeliveryCost() {
    return this.MeetDeliveryShreshold()
      ? 0
      : this.deliveryShreshold - this.GetTotalPrice()
  }

  GetChoosedGoods() {
    return this.goodsList.filter((goodsInfo) => goodsInfo.choose > 0)
  }

  GetSelectedNum() {
    return this.goodsList.reduce((acc, item) => acc + item.choose, 0)
  }

  GetRemainDeliveryThreshold() {
    return parseFloat(
      (this.deliveryShreshold - this.GetTotalPrice()).toFixed(2)
    )
  }

  constructor(gl) {
    const frozenGoodsList = Object.freeze([...gl])
    Object.defineProperty(this, 'goodsList', {
      get() {
        return frozenGoodsList
      },
      set() {
        throw new Error('goodsList属性是只读的，不能重新赋值')
      },
      configurable: false
    })

    Object.defineProperty(this, 'deliveryShreshold', {
      get() {
        return 30
      }
    })

    Object.defineProperty(this, 'deliveryCost', {
      get() {
        return 5
      }
    })

    Object.seal(this)
  }
}

// 冻结原型防止修改
Object.freeze(GoodsInfo.prototype)
Object.freeze(OrderInfo.prototype)

var doms = {
  orderContent: document.querySelector('.order-content'),

  shoppingCarBg: document.querySelector('.shoppingCarBg'),
  shoppingCar: document.querySelector('.shoppingCar'),
  shoppingCarNum: document.querySelector('.shoppingCarNum'),
  shoppingCarTotal: document.querySelector('.shoppingCarTotal'),
  deliveryThresholdBtn: document.querySelector('.deliveryThresholdBtn'),
  underDeliveryThreshold: document.querySelector('.underDeliveryThreshold'),
  reachDeliveryThreshold: document.querySelector('.reachDeliveryThreshold'),
  remainDeliveryThreshold: document.querySelector('.remainDeliveryThreshold')
}

var shopCarRect = doms.shoppingCar.getBoundingClientRect()
// 获取购物车中心坐标函数
function getShoppingCarPosition() {
  return {
    x: shopCarRect.left + shopCarRect.width / 2,
    y: shopCarRect.top + shopCarRect.height / 2
  }
}

// 在文档中添加用于动画的元素样式
var addTweenStyle = document.createElement('style')
addTweenStyle.innerHTML = `
  .add-tween {
    z-index: 1000;
    transform: translate(-50%, -50%);
  }
`
document.head.appendChild(addTweenStyle)

var orderInfo
InitGoodsInfo()
InitGoodsContentHTML()

function InitGoodsInfo() {
  var goodsList = []
  for (var i = 0; i < goods.length; i++) {
    goodsList.push(new GoodsInfo(goods[i]))
  }
  orderInfo = new OrderInfo(goodsList)
  //将orderInfo对象挂载到window对象上，方便调试
  window.orderInfo = orderInfo
}

function InitGoodsContentHTML() {
  var domFrag = document.createDocumentFragment()
  for (let i = 0; i < orderInfo.goodsList.length; i++) {
    var goodsInfo = orderInfo.goodsList[i]
    var div = document.createElement('div')
    div.classList.add(
      'good-item',
      'flex',
      'h-28',
      'w-full',
      'items-center',
      'justify-center',
      'shadow-2xs'
    )
    div.innerHTML = `
          <div class="good-img h-24 w-24 shadow-md">
            <img
              src="${goodsInfo.goods.pic}"
              class="h-auto w-full object-cover"
              alt=""
            />
          </div>
          <div class="good-info flex h-24 w-48 flex-col gap-0.5 px-2">
            <p class="text-left text-lg font-semibold">${goodsInfo.goods.title}</p>
            <p class="truncate text-xs">
            ${goodsInfo.goods.desc}
            </p>
            <div class="flex gap-2 text-xs text-gray-500">
              <p>月售${goodsInfo.goods.sellNumber}</p>
              <p>好评率${goodsInfo.goods.favorRate}%</p>
            </div>
            <div class="flex justify-between text-xs text-orange-500">
              <p>￥<span class="text-lg font-semibold">${goodsInfo.goods.price}</span></p>
              <div class="flex justify-end gap-1">
                <div
                  class="goods-reduce-${i} hidden iconfont icon-a-remove text-lg/8 text-sky-500" onclick="ReduceGoods(${i})"
                ></div>
                <span class="goods-choose-num-${i} hidden text-lg/8 text-stone-900"
                  >${goodsInfo.choose}</span
                >
                <div
                  class="goods-add-${i} iconfont icon-zengjia3 text-lg/8 text-sky-500" onclick="AddGoods(${i})"
                ></div>
            </div>
          </div>`
    domFrag.appendChild(div)
  }
  doms.orderContent.appendChild(domFrag)
}

window.ReduceGoods = function (index) {
  orderInfo.ReduceGoods(index)

  updateGoodsChooseUi(index)
  updateFooterUi()
}

window.AddGoods = function (index) {
  orderInfo.AddGoods(index)

  updateGoodsChooseUi(index)
  updateFooterUi()

  showTween(index)
}

function updateGoodsChooseUi(index) {
  var goodsReduceDiv = document.querySelector(`.goods-reduce-${index}`)
  goodsReduceDiv.classList.remove('hidden')
  var goodsChooseNumDiv = document.querySelector(`.goods-choose-num-${index}`)
  goodsChooseNumDiv.classList.remove('hidden')
  goodsChooseNumDiv.textContent = orderInfo.goodsList[index].choose
  if (orderInfo.goodsList[index].choose == 0) {
    goodsReduceDiv.classList.add('hidden')
    goodsChooseNumDiv.classList.add('hidden')
  }
}

function updateFooterUi() {
  var totalPrice = orderInfo.GetTotalPrice()
  doms.shoppingCarTotal.textContent = totalPrice
  if (totalPrice > 0) {
    doms.shoppingCar.classList.remove('bg-zinc-700')
    doms.shoppingCar.classList.add('bg-blue-500')
    doms.shoppingCarNum.classList.remove('hidden')
    doms.shoppingCarNum.textContent = orderInfo.GetSelectedNum()
  } else {
    doms.shoppingCar.classList.remove('bg-blue-500')
    doms.shoppingCar.classList.add('bg-zinc-700')
    doms.shoppingCarNum.classList.add('hidden')
  }

  if (orderInfo.MeetDeliveryShreshold()) {
    doms.deliveryThresholdBtn.classList.remove('bg-zinc-500')
    doms.deliveryThresholdBtn.classList.add('bg-green-500')
    doms.underDeliveryThreshold.classList.add('hidden')
    doms.reachDeliveryThreshold.classList.remove('hidden')
  } else {
    doms.deliveryThresholdBtn.classList.remove('bg-green-500')
    doms.deliveryThresholdBtn.classList.add('bg-zinc-500')
    doms.underDeliveryThreshold.classList.remove('hidden')
    doms.reachDeliveryThreshold.classList.add('hidden')
    doms.remainDeliveryThreshold.textContent =
      orderInfo.GetRemainDeliveryThreshold()
  }
}

function showTween(index) {
  var addTween = document.querySelector('.add-tween')

  var startDiv = document.querySelector(`.goods-add-${index}`)
  var startRect = startDiv.getBoundingClientRect()
  var startV2 = {
    x: startRect.left + startRect.width / 2,
    y: startRect.top + startRect.height / 2
  }

  // 获取当前购物车位置
  var shoppingCarV2 = getShoppingCarPosition()

  // 设置起始位置
  addTween.style.left = startV2.x + 'px'
  addTween.style.top = startV2.y + 'px'
  addTween.classList.remove('hidden')

  // 强制重绘
  addTween.offsetHeight

  // 设置目标位置和过渡效果
  addTween.style.transition =
    'top 0.5s cubic-bezier(0.25, -0.55, 0.83, 0.13), left 0.5s linear'
  addTween.style.left = shoppingCarV2.x + 'px'
  addTween.style.top = shoppingCarV2.y + 'px'

  // 动画结束后隐藏元素
  setTimeout(() => {
    addTween.style.transition = ''
    addTween.classList.add('hidden')
    showShopCarTween()
  }, 450)
}

function showShopCarTween() {
  var carDiv = doms.shoppingCarBg

  // 创建关键帧动画
  const keyframes = [
    { transform: 'scale(0.8)' }, // 0%
    { transform: 'scale(1.2)' }, // 25%
    { transform: 'scale(0.9)' }, // 50%
    { transform: 'scale(1.1)' }, // 75%
    { transform: 'scale(1)' } // 100%
  ]

  // 动画选项
  const options = {
    duration: 500, // 500毫秒
    easing: 'linear',
    fill: 'forwards'
  }

  // 执行动画
  carDiv.animate(keyframes, options)
}
